'use strict';
const {
  Model
} = require('sequelize');
const bcrypt = require("bcryptjs")
const {BadRequest} = require("http-errors")
module.exports = (sequelize, DataTypes) => {
  class User extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      models.User.hasMany(models.Course,{as:"courses"})
      models.User.belongsToMany(models.Course,{through:models.Likes,foreignKey:'userId',as:'likeCourses'})
      models.User.hasMany(models.Attachment,{as:"attachments"})
    }
  }
  User.init({
    email: {
      type:DataTypes.STRING,
      allowNull: false,
      validate:{
        notNull:{msg:"邮箱必须填写"},
        notEmpty:{msg:"邮箱不能为空"},
        isEmail:{msg:"邮箱格式不正确"},
        async isUnique(value){
          const user = await User.findOne({
            where:{
              email:value
            }
          })
          if(user){
            throw new Error("邮箱已存在,请直接登录")
          }
        }
      }
    },
    username: {
      type:DataTypes.STRING,
      allowNull:false,
      validate:{
        notNull:{msg:"用户名必须填写"},
        notEmpty:{msg:"用户名不能为空"},
        len:{
          args:[2,45],
          msg:"用户名长度必须在2-45之间"
        },
        async isUnique(value){
          const user = await User.findOne({
            where:{
              username:value
            }
          })
          if(user){
            throw new Error("用户名已存在")
          }
        }
      }
    },
    password: {
      type:DataTypes.STRING,
      allowNull:false,
      validate:{
        notNull:{msg:"密码必须填写"},
        notEmpty:{msg:"密码不能为空"},
      },
      // set里面的东西，不属于Sequelize的自定义验证了。不会被转成SequelizeValidationError
      set(value){
        // 检查是否为空
        if(!value){
          throw new BadRequest('密码必须填写')
        }
        // 检查长度
        if(value.length <6 && value.length > 45){
          throw new BadRequest("密码长度必须在6-45之间")
        }
        // 如果通过所有验证，进行hash处理并设置值
        this.setDataValue("password",bcrypt.hashSync(value,10))
      }
    },
    nickname: {
      type:DataTypes.STRING,
      allowNull:false,
      validate:{
        notNull:{msg:"昵称必须填写"},
        notEmpty:{msg:"昵称不能为空"},
        len:{
          args:[2,45],
          msg:"昵称长度必须在2-45之间"
        }
      }
    },
    sex: {
      type:DataTypes.TINYINT,
      allowNull:false,
      validate:{
        notNull:{msg:"性别必须填写"},
        notEmpty:{msg:"性别不能为空"},
        isIn:{
          args:[[0,1,2]],
          msg:"性别的值必须是：男性：0，女性：1，未选择：2"
        }
      }
    },
    avatar: {
      type:DataTypes.STRING,
      validate:{
        isUrl:{
          msg:"头像必须是一个有效的URL"
        }
      }
    },
    company: DataTypes.STRING,
    introduce: DataTypes.TEXT,
    role: {
      type:DataTypes.TINYINT,
      allowNull:false,
      validate:{
        notNull:{msg:"角色必须填写"},
        notEmpty:{msg:"角色不能为空"},
        isIn:{
          args:[[0,100]],
          msg:"角色的值必须是：普通用户：0，管理员：100"
        }
      }
    }
  }, {
    sequelize,
    modelName: 'User',
  });
  return User;
};